﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.Mvc;
using XRM.Security.DataAccess.Models;
using XRM.Security.WebUI.Enums;
using XRM.Security.WebUI.Helpers;
using XRM.Security.WebUI.Models.IdentityCenter;

namespace XRM.Security.WebUI.Controllers
{
    [System.Web.Mvc.Authorize]
    public class IdentityCenterController : BaseController
    {
        [System.Web.Mvc.Authorize(Roles = "Administrator, IdentityCenterViewer, IdentityCenterEditor")]
        public ActionResult Index()
        { 
            var model = IdentityCenterRepository.GetAll( s => s.IsDeleted == false )
                .Select(s => new IdentityCenterModel
                    {
                        Address = s.Address,
                        Contact = s.Contact,
                        Id = s.IdentityCenterId,
                        IdentityCenterName = s.IdentityCenterName
                    }).ToList();
            return View(model);
        }
        
        [System.Web.Mvc.HttpGet]
        [System.Web.Mvc.Authorize(Roles = "Administrator, IdentityCenterViewer, IdentityCenterEditor")]
        public ActionResult Edit(int id)
        {
            var identityCenter = IdentityCenterRepository.Get( id );
            if (identityCenter == null)
                throw new HttpResponseException(HttpStatusCode.NotFound);

            var model = new IdentityCenterModel( identityCenter );
            model.GetInfoSystemAll(InfoSystemRepository.GetAll(x => x.InMaintenance).OrderBy(x => x.InfoSystemName).ToList());
            model.ReadOnly = !Permission.AllowIdentityCenterEdit();
            return View(model);
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, IdentityCenterEditor")]
        public ActionResult Edit(IdentityCenterModel model)
        {
            model.InfoSystemList = model.InfoSystemList.Where(x => x.Id > 0).ToList();
            foreach (var item in model.InfoSystemList)
            {
                item.InfoSystemName = InfoSystemRepository.Get(item.Id).InfoSystemName;
            }
            model.GetInfoSystemAll(InfoSystemRepository.GetAll(x => x.InMaintenance).OrderBy(x => x.InfoSystemName).ToList());
            model.GetFiles(IdentityCenterRepository.Get(model.Id));

            ModelState.Clear();
            TryValidateModel(model);
            if (!ModelState.IsValid)
            {
                ShowAlert(AlertType.Error, GetModelErrors());
                return View(model);
            }

            if (model.InfoSystemList.Select(x => x.InfoSystemName).Distinct().Count() != model.InfoSystemList.Count())
            {
                ShowAlert(AlertType.Error, "Информационные системы не уникальны");
                return View(model);
            }
            
            IdentityCenter identityCenter = new IdentityCenter();
            if (model.IsEdit)
            {
                identityCenter = IdentityCenterRepository.Get(model.Id);
                identityCenter.IdentityCenterInfoSystems.Clear();
                IdentityCenterRepository.Update(identityCenter);
            }

            identityCenter.Address = model.Address;
            identityCenter.Contact = model.Contact;

            List<IdentityCenterInfoSystem> identityCenterInfoSystem = model.InfoSystemList.Select(x => new IdentityCenterInfoSystem { IdentityCenterId = identityCenter.IdentityCenterId, InfoSystemId = x.Id.Value }).ToList();
            foreach (IdentityCenterInfoSystem item in identityCenterInfoSystem)
            {
                identityCenter.IdentityCenterInfoSystems.Add(item);
            }

            IdentityCenterRepository.Update(identityCenter);

            if (model.IsEdit)
                ShowAlert(AlertType.Success, "Информационная система отредактирована успешно");
            else
                ShowAlert(AlertType.Success, "Информационная система создана успешно");

            return RedirectToAction("Index");
        }

        [System.Web.Mvc.Authorize(Roles = "Administrator, IdentityCenterEditor")]
        public ActionResult Delete(int id)
        {
            var identityCenter = IdentityCenterRepository.Get(id);
            if (identityCenter == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            identityCenter.IsDeleted = true;
            IdentityCenterRepository.Update(identityCenter);
            ShowAlert(AlertType.Success, "Информационная система удалена успешно");
        
            return RedirectToAction("Index");
        }

        [System.Web.Mvc.HttpPost]
        public ActionResult AddCertificate(int identityCenterId, string dataId)
        {
            var certData = Session[dataId] as UploadCertTempData;
            if (certData == null || certData.RootCertificate == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            var identityCenter = IdentityCenterRepository.Get( identityCenterId );
            if (identityCenter == null)
                throw new HttpResponseException( HttpStatusCode.BadRequest );

            var cert = certData.RootCertificate;
            if ( IdentityCenterCertRepository.GetAll( s => s.Thumbprint == cert.Thumbprint ).Any() )
                return JsonError( String.Format( "Сертификат с отпечатком '{0}' уже был загружен", cert.Thumbprint ) );

            identityCenter.IsDeleted = false;
            IdentityCenterModel.AddCertificate(identityCenter, cert, certData.FileName);
            IdentityCenterRepository.Update(identityCenter);

            ShowAlert( AlertType.Success, "Сертификат успешно загружен." );
            return Json(new {isSuccess = true});
        }

        [System.Web.Mvc.HttpGet]
        [System.Web.Mvc.Authorize( Roles = "Administrator, IdentityCenterEditor, IdentityCenterViewer" )]
        public ActionResult DownloadIdentityCenterFile(int id)
        {
            var cert = IdentityCenterCertRepository.Get(id);
            if (cert == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            return File( cert.FileData, "application/octet-stream", String.Format( "{0}.cer", cert.FileName ) );
        }
    }
}
